﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MDT_MonitorModel;

namespace MDT_Metro_monitoring
{
    public class Server : MDT_MonitorModel.IComputer
    {
        
        private string name;
        [System.Xml.Serialization.XmlElement]
        private string ipaddress;
        [System.Xml.Serialization.XmlElement]
        private string port;
        
        private bool online;
        
        private bool ready;
        [System.Xml.Serialization.XmlElement]
        private string errorStatus;

        internal bool isFake;

        [System.Xml.Serialization.XmlIgnore]
        private List<Computer> clients;

        [System.Xml.Serialization.XmlIgnore]
        private ODataSampleViewModel clientData;

        [System.Xml.Serialization.XmlIgnore]
        internal ODataSampleViewModel ClientData
        {
            get
            {
                if (clientData == null)
                {
                try
                {
                    this.clientData = new ODataSampleViewModel(this.Id, this.Port);
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
                }
                return clientData;
            }
            set
            {
                this.clientData = value;
            }
        }

        [System.Xml.Serialization.XmlIgnore]
        public String NbClient
        {
            get
            {
                if (ready)
                {
                    if (clients != null)
                        return clients.Count.ToString();
                    else
                        return "0";
                }
                else
                {
                    return "...";
                }
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String NbClientError
        {
            get
            {
                if (ready)
                {
                    if (clients != null)
                    {
                        var result = from cp in clients where cp.Errors != 0 select cp;
                        return result.Count().ToString();
                    }
                    else
                        return "...";
                }
                else
                {
                    return "";
                }

            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String NbClientWarning
        {
            get
            {
                if (ready)
                {
                    if (clients != null)
                    {
                        var result = from cp in clients where cp.Warnings != 0 select cp;
                        return result.Count().ToString();
                    }
                    else
                        return "...";
                }
                else
                {
                    return "";
                }

            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String StatusColor
        {
            get
            {
                if (Online)
                    return "Green";
                else
                    return "Orange";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string Type
        {
            get
            {
                return "Servers";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String ErrorColor
        {
            get
            {
                if (NbClientError != "0" && NbClientError != "" && NbClientError != "...")
                    return "Tomato";
                else
                    return "DarkCyan";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String WarningColor
        {
            get
            {
                if (NbClientWarning != "0" && NbClientWarning != "" && NbClientWarning != "...")
                    return "Orange";
                else
                    return "DarkCyan";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public bool Online
        {
            get
            {
                return online;
            }

            set
            {
                online = value;
            }

        }
        [System.Xml.Serialization.XmlIgnore]
        public int StatusId
        {
            get
            {
                if (Online)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String Status
        {
            get
            {
                if (isFake)
                    return "";

                if (Online)
                {
                    return "Online";
                }
                else
                {
                    return "Offline";
                }
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public String NbClientInstalled
        {
            get
            {
                if (ready)
                {
                    if (clients != null)
                    {
                        var result = from cp in clients where cp.EndTime != null select cp;
                        return result.Count().ToString();
                    }
                    else
                        return "...";
                }
                else
                {
                    return "na";
                }

            }
        }
        
        [System.Xml.Serialization.XmlIgnore]
        public string PercentCompleteStr
        {
            get
            {
                if (isFake)
                    return "Add a new server";
                if (ready && this.Clients != null)
                {
                    int percent = 0;
                    int nbClient = 0;

                    if (this.Clients != null)
                        nbClient = this.Clients.Count;

                    foreach (Computer c in this.Clients)
                    {
                        percent += Convert.ToInt16(c.PercentComplete);
                    }
                    if (nbClient == 0)
                        return "--";
                    else
                        return (percent / nbClient).ToString()+"%";
                }
                return "--";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string data1String
        {
            get
            {
                if (isFake)
                    return ""; 
                return "Nb Clients:";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string data1Text
        {
            get
            {
                if (isFake)
                    return ""; 
                return this.NbClient;
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string data2String
        {
            get
            {
                if (isFake)
                    return ""; 
                return "Nb Clients Error:";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string data2Text
        {
            get
            {
                if (isFake)
                    return ""; 
                return this.NbClientError;
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string data3String
        {
            get
            {
                if (isFake)
                    return ""; 
                return "Nb Clients Warning:";
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public string data3Text
        {
            get
            {
                if (isFake)
                    return ""; 
                return this.NbClientWarning;
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public object sort1
        {
            get
            {
                if (isFake)
                    return ""; 
                return this.Status;
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public object sort2
        {
            get
            {
                if (isFake)
                    return ""; 
                return this.NbClientError;
            }
        }
        [System.Xml.Serialization.XmlIgnore]
        public object sort3
        {
            get
            {
                if (isFake)
                    return ""; 
                return this.NbClientWarning;
            }
        }


        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public string Ipaddress
        {
            get
            {
                return ipaddress;
            }
            set
            {
                ipaddress = value;
            }
        }

        public string Port
        {
            get
            {
                return port;
            }
            set
            {
                port = value;
            }
        }

        public Server()
        {
            ipaddress = "";
            name = "";
            errorStatus = "";
            port = "";
            ready = false;
            online = false;
            clients = null;
        }

        public Server(string id, string port)
            : this()
        {
            if (System.Text.RegularExpressions.Regex.IsMatch(id, "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"))
            {
                this.ipaddress = id;
            }
            else
            {
                this.name = id;
            }

            this.port = port;

            try
            {
                this.ClientData = new ODataSampleViewModel(this.Id, this.Port);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        public string Id
        {
            get
            {
                if (ipaddress != "")
                    return ipaddress;
                else
                    return name;
            }
            set
            {
                if (System.Text.RegularExpressions.Regex.IsMatch(value, "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"))
                {
                    this.ipaddress = value;
                }
                else
                {
                    this.name = value;
                }
            }
        }

        public string Image
        {
            get
            {
                if (isFake)
                    return "ms-appx:///Assets/plus.png";
                else
                    return "ms-appx:///Assets/surface.png";
            }
        }

        internal async Task<bool> testConnectivity()
        {
            System.Net.Http.HttpResponseMessage res;
            try
            {
                System.Net.Http.HttpClient test = new System.Net.Http.HttpClient();
                res = await test.GetAsync("http://" + this.Id + ":" + this.Port + "/MDTMonitorData");
            }
            catch (System.Net.Http.HttpRequestException)
            {
                this.Online = false;
                this.ready = false;
                return this.Online;
            }
            catch (Exception e)
            {
                this.errorStatus = e.Message;
                this.Online = false;
                this.ready = false;
                return this.Online;
            }

            this.Online = (res.StatusCode == System.Net.HttpStatusCode.OK);
            this.ready = true;
            return this.Online;
        }

        internal List<Computer> Clients
        {
            get
            {
                return clients;
            }

            set
            {
                clients = value;
            }

        }


        public string ErrorStatus
        {
            get
            {
                return this.errorStatus;
            }
        }
    }
}
